home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // ObjectWindows
- // Copyright (c) 1995, 1997 by Borland International, All Rights Reserved
- //
- //$Revision: 10.21 $
- //
- // Implementation of Pane Splitter classes
- //----------------------------------------------------------------------------
- #include <owl/pch.h>
- #if !defined(OWL_LAYOUTWI_H)
- # include <owl/layoutwi.h>
- #endif
- #if !defined(OWL_PANESPLI_H)
- # include <owl/panespli.h>
- #endif
- #if !defined(OWL_UIHELPER_H)
- # include <owl/uihelper.h>
- #endif
- #if !defined(OWL_DC_H)
- # include <owl/dc.h>
- #endif
- #if !defined(WINSYS_UIMETRIC_H)
- # include <winsys/uimetric.h>
- #endif
- #if !defined(CLASSLIB_STACKS_H)
- # include <classlib/stacks.h>
- #endif
- #include <math.h>
-
- OWL_DIAGINFO;
-
- //
- // Defines to make typesafe downcasting simpler.
- //
- #define SPLITTER(x) TYPESAFE_DOWNCAST(x,TSplitter)
- #define LAYOUTWINDOW(x) TYPESAFE_DOWNCAST(x,TLayoutWindow)
- //#define USE_CUSTOM_CURSORS
-
- //----------------------------------------------------------------------------
- // TSplitter class.
- //
-
- DEFINE_RESPONSE_TABLE1(TSplitter, TLayoutWindow)
- EV_WM_LBUTTONDOWN,
- EV_WM_MOUSEMOVE,
- EV_WM_LBUTTONUP,
- EV_WM_SETCURSOR,
- EV_WM_SIZE,
- END_RESPONSE_TABLE;
-
- //
- // Constructor for abstract base class - don't set a border.
- //
- TSplitter::TSplitter(TWindow* parent, TPaneSplitter* ps, float percent)
- :
- TLayoutWindow(parent, 0, 0),
- PercentOf(percent),
- PaneSplitter(ps)
- {
- Attr.Style &= ~WS_BORDER;
- Attr.Style |= WS_CLIPCHILDREN;
- }
-
- //
- // Notify TPaneSplitter object that it should begin the splitter move process.
- //
- void
- TSplitter::EvLButtonDown(uint /*modKeys*/, TPoint& point)
- {
- TPoint p = point;
- MapWindowPoints(0, &p, 1); // map to screen
- PaneSplitter->StartSplitterMove(this, p);
- // TLayoutWindow::EvLButtonDown(modKeys, point);
- }
-
- //
- // Notify TPaneSplitter object that splitter has moved.
- //
- void
- TSplitter::EvMouseMove(uint /*modKeys*/, TPoint& point)
- {
- TPoint p = point;
- MapWindowPoints(0, &p, 1); // map to screen
- PaneSplitter->MouseMoved(p);
- // TLayoutWindow::EvMouseMove(modKeys, point);
- }
-
- //
- // Notify TPaneSplitter object that splitters have finished being moved.
- //
- void
- TSplitter::EvLButtonUp(uint /*modKeys*/, TPoint& /*point*/)
- {
- PaneSplitter->EndSplitterMove();
- // TLayoutWindow::EvLButtonUp(modKeys, point);
- }
-
- //
- // Notify TPaneSplitter object that it should set the appropriate cursor.
- //
- bool
- TSplitter::EvSetCursor(THandle hWndCursor, uint hitTest, uint mouseMsg)
- {
- TPoint p;
- if (hWndCursor == GetHandle() && hitTest == HTCLIENT) {
- GetCursorPos(p);
- PaneSplitter->SetSplitterMoveCursor(this, p);
- }
- else
- TLayoutWindow::EvSetCursor(hWndCursor, hitTest, mouseMsg);
- return true;
- }
-
- //
- // Notify TPaneSplitter object that splitter needs to be repainted.
- // This allows the user to draw the splitter.
- //
- void
- TSplitter::Paint(TDC& dc, bool, TRect& rect)
- {
- TLayoutWindow::Paint(dc, true, rect);
- PaneSplitter->DrawSplitter(dc, GetRect());
- }
-
- //
- // Resize the splitter. In certain situations the splitters that are
- // nested in this splitter don't want to resize, in which case their
- // sizes are adjusted (retained).
- //
- void
- TSplitter::EvSize(uint sizeType, TSize& size)
- {
- if (sizeType != SIZE_MINIMIZED && PaneSplitter->PaneSplitterResizing)
- AdjForResize(size);
- TLayoutWindow::EvSize(sizeType, size);
- }
-
- //
- // Common code for T*Splitter::Setup(). Sets pane's parent to this and
- // sets their layout metrics.
- //
- void
- TSplitter::SetupEpilog(TSplitter* s, TWindow* targetPane, TWindow* newPane,
- TLayoutMetrics& lmOfTargetPane,
- TLayoutMetrics& lmOfNewPane)
- {
- targetPane->SetParent(s);
- newPane->SetParent(s);
- newPane->Create();
- SetChildLayoutMetrics(*targetPane, lmOfTargetPane);
- SetChildLayoutMetrics(*newPane, lmOfNewPane);
- }
-
- //
- // Remove a pane from this splitter.
- //
- TLayoutWindow*
- TSplitter::RemovePane(TWindow* pane, TShouldDelete::TDelete dt)
- {
- // 'parentSplitter' represents the splitter 'this' splitter is contained in.
- // 'retval' indicates weather their is a parent splitter, if not then 'pane'
- // is only one.
- // 'otherPane' is other window contained in this splitter.
- //
- TSplitter* parentSplitter = SPLITTER(Parent);
- TLayoutWindow* retval = parentSplitter;
- TWindow* otherPane = Pane1() == pane ? Pane2() : Pane1();
-
- TLayoutMetrics lm1;
- TLayoutMetrics lm2;
- TLayoutMetrics lm3;
-
- pane->ShowWindow(SW_HIDE);
- if (parentSplitter) {
- TWindow* p1 = parentSplitter->Pane1();
- TWindow* p2 = parentSplitter->Pane2();
-
- parentSplitter->GetChildLayoutMetrics(*p1, lm1);
- parentSplitter->GetChildLayoutMetrics(*p2, lm2);
- pane->SetParent(0); // remove pane.
- otherPane->SetParent(parentSplitter); // move up one level.
-
- if (this == p1) { // if top or left pane is being removed.
- if (lm2.X.RelWin == this) // adjust other panes layout metrics.
- lm2.X.RelWin = otherPane;
- else if (lm2.Y.RelWin == this)
- lm2.Y.RelWin = otherPane;
- parentSplitter->SetChildLayoutMetrics(*p2, lm2);
- parentSplitter->SetChildLayoutMetrics(*otherPane, lm1);
- }
- else { // other pane's layout is same as one being removed.
- //
- parentSplitter->SetChildLayoutMetrics(*otherPane, lm2);
- }
- }
- else { // remove last pane.
- retval = LAYOUTWINDOW(Parent);
- TLayoutMetrics lmOfOtherPane;
-
- PaneSplitter->GetDefLM(lmOfOtherPane);
- otherPane->SetParent(retval);
- pane->SetParent(0);
- retval->SetChildLayoutMetrics(*otherPane, lmOfOtherPane);
- }
- // Destroy pane.
- //
- RemoveChildLayoutMetrics(*pane);
- PaneSplitter->DestroyPane(pane, dt);
- return retval;
- }
-
- //----------------------------------------------------------------------------
- // TVSplitter class.
- //
-
- //
- // Constructor for a vertical splitter
- //
- TVSplitter::TVSplitter(TWindow* parent, TPaneSplitter* ps, float percent)
- :
- TSplitter(parent, ps, percent)
- {
- SetCaption("VSplitter");
- }
-
- //
- // Return TRect for the visible area (in client coordinates) of splitter.
- //
- TRect
- TVSplitter::GetRect()
- {
- TRect rect;
- TWindow* p1 = Pane1();
-
- rect.left = p1->Attr.X + p1->Attr.W;
- rect.top = p1->Attr.Y;
- rect.right = rect.left + PaneSplitter->GetSplitterWidth();
- rect.bottom = p1->Attr.Y + p1->Attr.H;
-
- return rect;
- }
-
- //
- // Split given pane into 2 parts: itself and a new pane.
- //
- void
- TVSplitter::Split(TWindow* targetPane, TWindow* newPane, TSplitDirection sd, float percent)
- {
- // Panes contained in this splitter.
- //
- TWindow* p1 = Pane1();
- TWindow* p2 = Pane2();
- TLayoutMetrics lm;
-
- GetChildLayoutMetrics(*p2, lm);
-
- // Create new splitter (will be a child of this splitter).
- //
- TSplitter* splitter;
- if (sd == psHorizontal)
- splitter = new THSplitter(this, PaneSplitter, percent);
- else
- splitter = new TVSplitter(this, PaneSplitter, percent);
-
- // Initialize new splitter by putting target and new pane into it.
- //
- splitter->Create();
- TLayoutMetrics lmOfSplitter = splitter->Setup(targetPane, newPane, percent);
-
- if (p1 == targetPane) { // target pane == left pane. adjust new splitter's
- // width and other windows left edge to be
- // adjacent to new splitter.
- //
- lmOfSplitter.Width.Absolute(targetPane->Attr.W);
-
- lm.X.RelWin = splitter;
- SetChildLayoutMetrics(*p2, lm);
- }
- else { // set new splitter to the right of left pane.
- //
- lmOfSplitter.X.RightOf(p1, PaneSplitter->GetSplitterWidth());
- }
- SetChildLayoutMetrics(*splitter, lmOfSplitter);
- }
-
- //
- // Setup layout metrics and children for new splitter. Return that
- // layout metrics.
- //
- TLayoutMetrics
- TVSplitter::Setup(TWindow* targetPane, TWindow* newPane, float percent)
- {
- TLayoutMetrics lmOfSplitter;
- TLayoutMetrics lmOfPane1;
- TLayoutMetrics lmOfPane2;
-
- PaneSplitter->GetDefLM(lmOfSplitter);
- lmOfPane1 = lmOfPane2 = lmOfSplitter;
-
- // Target pane's width is 1/2 of what it was. New pane is to the right
- // of target pane.
- //
- lmOfPane1.Width.Absolute(targetPane->Attr.W * percent);
- lmOfPane2.X.RightOf(targetPane, PaneSplitter->GetSplitterWidth());
- SetupEpilog(this, targetPane, newPane, lmOfPane1, lmOfPane2);
-
- return lmOfSplitter;
- }
-
- //
- // Create splitter indicator for this splitter.
- //
- TSplitterIndicator*
- TVSplitter::CreateSplitterIndicator()
- {
- return new TVSplitterIndicator(this, GetScreenRect());
- }
-
- //
- // Return left pane, or 0 if none exist.
- //
- TWindow*
- TVSplitter::Pane1()
- {
- TWindow* p1 = GetFirstChild();
- if (p1) {
- TWindow* p2 = p1->Next();
-
- return p1->Attr.X <= p2->Attr.X ? p1 : p2;
- }
- return 0;
- }
-
- //
- // Return right pane, or 0 if none exist.
- //
- TWindow*
- TVSplitter::Pane2()
- {
- if (NumChildren() != 2)
- return 0;
-
- TWindow* p1 = GetFirstChild();
- TWindow* p2 = p1->Next();
-
- return p1->Attr.X > p2->Attr.X ? p1 : p2;
- }
-
- //
- // Called as a result of parent being resized. Adjust width of pane 1 to make
- // it appear this splitter didn't move.
- //
- void
- TVSplitter::AdjForResize(const TSize& sz)
- {
- TLayoutMetrics lm;
- TWindow* pane = Pane1();
-
- if (pane) {
- GetChildLayoutMetrics(*pane, lm);
- lm.Width.Absolute(GetPercent() * sz.cx);
- SetChildLayoutMetrics(*pane, lm);
- }
- }
-
- //
- // Move splitter given distance. Accomplished by resizing pane 1.
- //
- void
- TVSplitter::Move(int dist)
- {
- TLayoutMetrics lm;
- TWindow* pane = Pane1();
-
- if (pane) {
- GetChildLayoutMetrics(*pane, lm);
- lm.Width.Absolute(lm.Width.Value + dist);
- SetChildLayoutMetrics(*pane, lm);
-
- // Calc new percent.
- //
- PercentOf = (float)lm.Width.Value / (float)Attr.W;
-
- // Update nested splitters to retain their positions.
- //
- TSplitter* splitter = SPLITTER(Pane2());
- if (splitter) {
- while (1) {
- if (splitter->SplitDirection() == SplitDirection()) {
- TLayoutMetrics lm;
- splitter->GetChildLayoutMetrics(*splitter->Pane1(), lm);
- lm.Width.Absolute(lm.Width.Value - dist);
- splitter->SetPercent((float)lm.Width.Value /
- (float)(splitter->Attr.W - dist));
- splitter->SetChildLayoutMetrics(*splitter->Pane1(), lm);
- }
- if ((splitter = SPLITTER(splitter->Pane1())) == 0)
- break;
- }
- }
- }
- }
-
- //
- // Change the width of the splitter and then do a Layout() to see changes.
- //
- void
- TVSplitter::AdjSplitterWidth(int w)
- {
- TLayoutMetrics lm;
-
- GetChildLayoutMetrics(*Pane2(), lm);
- lm.X.Value += w;
- SetChildLayoutMetrics(*Pane2(), lm);
- Layout();
- }
-
- //----------------------------------------------------------------------------
- // THSplitter class.
- //
-
- //
- // Constructor for a horizontal splitter
- //
- THSplitter::THSplitter(TWindow* parent, TPaneSplitter* ps, float percent)
- :
- TSplitter(parent, ps, percent)
- {
- SetCaption("HSplitter");
- }
-
- //
- // Return TRect for the visible area (in client coordinates) of splitter.
- //
- TRect
- THSplitter::GetRect()
- {
- TRect rect;
- TWindow* p1 = Pane1();
-
- rect.left = p1->Attr.X;
- rect.top = p1->Attr.Y + p1->Attr.H;
- rect.right = p1->Attr.X + p1->Attr.W;
- rect.bottom = rect.top + PaneSplitter->GetSplitterWidth();
-
- return rect;
- }
-
- //
- // Split given pane into 2 parts: itself and a new pane.
- //
- void
- THSplitter::Split(TWindow* targetPane, TWindow* newPane, TSplitDirection sd, float percent)
- {
- // Panes contained in this splitter.
- //
- TWindow* p1 = Pane1();
- TWindow* p2 = Pane2();
- TLayoutMetrics lm;
-
- GetChildLayoutMetrics(*p2, lm);
-
- // Create new splitter (will be a child of this splitter).
- //
- TSplitter* splitter;
- if (sd == psHorizontal)
- splitter = new THSplitter(this, PaneSplitter, percent);
- else
- splitter = new TVSplitter(this, PaneSplitter, percent);
-
- // Initialize new splitter by putting target and new pane into it.
- //
- splitter->Create();
- TLayoutMetrics lmOfSplitter = splitter->Setup(targetPane, newPane, percent);
-
- if (p1 == targetPane) { // target pane == top pane. adjust new splitter's
- // height and other windows top edge to be
- // adjacent to new splitter.
- //
- lmOfSplitter.Height.Absolute(targetPane->Attr.H);
-
- lm.Y.RelWin = splitter;
- SetChildLayoutMetrics(*p2, lm);
- }
- else { // set new splitter to below top pane.
- //
- lmOfSplitter.Y.Below(p1, PaneSplitter->GetSplitterWidth());
- }
- SetChildLayoutMetrics(*splitter, lmOfSplitter);
- }
-
- //
- // Setup layout metrics and children for new splitter. Return that
- // layout metrics.
- //
- TLayoutMetrics
- THSplitter::Setup(TWindow* targetPane, TWindow* newPane, float percent)
- {
- TLayoutMetrics lmOfSplitter;
- TLayoutMetrics lmOfPane1;
- TLayoutMetrics lmOfPane2;
-
- PaneSplitter->GetDefLM(lmOfSplitter);
- lmOfPane1 = lmOfPane2 = lmOfSplitter;
-
- // Target pane's height is 1/2 of what it was. New pane is below
- // target pane.
- //
- lmOfPane1.Height.Absolute(targetPane->Attr.H * percent);
- lmOfPane2.Y.Below(targetPane, PaneSplitter->GetSplitterWidth());
- SetupEpilog(this, targetPane, newPane, lmOfPane1, lmOfPane2);
-
- return lmOfSplitter;
- }
-
- //
- // Create splitter indicator for this splitter.
- //
- TSplitterIndicator*
- THSplitter::CreateSplitterIndicator()
- {
- return new THSplitterIndicator(this, GetScreenRect());
- }
-
- //
- // Return top pane, or 0 if none exist.
- //
- TWindow*
- THSplitter::Pane1()
- {
- TWindow* p1 = GetFirstChild();
-
- if (p1) {
- TWindow* p2 = p1->Next();
-
- return p1->Attr.Y <= p2->Attr.Y ? p1 : p2;
- }
- return 0;
- }
-
- //
- // Return bottom pane, or 0 if none exist.
- //
- TWindow*
- THSplitter::Pane2()
- {
- if (NumChildren() != 2)
- return 0;
-
- TWindow* p1 = GetFirstChild();
- TWindow* p2 = p1->Next();
-
- return p1->Attr.Y > p2->Attr.Y ? p1 : p2;
- }
-
- //
- // Called as a result of parent being resized. Adjust height of pane 1 to make
- // it appear this splitter didn't move.
- //
- void
- THSplitter::AdjForResize(const TSize& sz)
- {
- TLayoutMetrics lm;
- TWindow* pane = Pane1();
-
- if (pane) {
- GetChildLayoutMetrics(*pane, lm);
- lm.Height.Absolute(GetPercent() * sz.cy);
- SetChildLayoutMetrics(*pane, lm);
- }
- }
-
- //
- // Move splitter given distance. Accomplished by resizing pane 1.
- //
- void
- THSplitter::Move(int dist)
- {
- TLayoutMetrics lm;
- TWindow* pane = Pane1();
-
- if (pane) {
- GetChildLayoutMetrics(*pane, lm);
- lm.Height.Absolute(lm.Height.Value + dist);
- SetChildLayoutMetrics(*pane, lm);
-
- // Calc new percent.
- //
- PercentOf = (float)lm.Height.Value / (float)Attr.H;
-
- // Update nested splitters to retain there relative positions.
- //
- TSplitter* splitter = SPLITTER(Pane2());
- if (splitter) {
- while (1) {
- if (splitter->SplitDirection() == SplitDirection()) {
- TLayoutMetrics lm;
- splitter->GetChildLayoutMetrics(*splitter->Pane1(), lm);
- lm.Height.Absolute(lm.Height.Value - dist);
- splitter->SetPercent((float)lm.Height.Value /
- (float)(splitter->Attr.H - dist));
- splitter->SetChildLayoutMetrics(*splitter->Pane1(), lm);
- }
- if ((splitter = SPLITTER(splitter->Pane1())) == 0)
- break;
- }
- }
- }
- }
-
- //
- // Change the width of the splitter and then do a Layout() to see changes.
- //
- void
- THSplitter::AdjSplitterWidth(int w)
- {
- TLayoutMetrics lm;
-
- GetChildLayoutMetrics(*Pane2(), lm);
- lm.Y.Value += w;
- SetChildLayoutMetrics(*Pane2(), lm);
- Layout();
- }
-
- //----------------------------------------------------------------------------
- // TSplitterIndicator class (Base class).
- //
-
- //
- // Draw splitter indicator. Use InvertRect() to create the effect.
- //
- void
- TSplitterIndicator::Draw()
- {
- if (!Showing) {
- Showing = true;
- TScreenDC screenDC;
- screenDC.InvertRect(*this);
- }
- }
-
- //----------------------------------------------------------------------------
- // TVSplitterIndicator class.
- //
-
- //
- // Connect either top or bottom side of indicator to either top or bottom side
- // of given TRect. If top of given TRect is below indicator then connect to
- // TRect's top, else if TRect is above indicator then connect to TRect's bottom.
- // Assumes that given TRect represents a horizontal indicator.
- //
- void
- TVSplitterIndicator::ConnectToRect(const TRect& rect)
- {
- if (rect.top > bottom)
- bottom = rect.top;
- else if (rect.top < top)
- top = rect.bottom;
- }
-
- //
- // Move splitter indicator (do not draw it though) given dist, which
- // could be + (move right) or - (move left). If the move would put the
- // indicator out of the move area then move to edge of move area.
- //
- void
- TVSplitterIndicator::Move(int dist)
- {
- TRect moveArea = Splitter->GetMoveArea();
- TRect orig = Splitter->GetScreenRect();
- int splitterWidth = right - left;
-
- left = orig.left + dist;
- right = left + splitterWidth;
- top = orig.top;
- bottom = orig.bottom;
-
- //
- // Don't allow the indicator to get closer to the edge of the moveArea
- // than the cushion.
- //
- if( moveArea.Width() > (Cushion) ) {
- moveArea.left += Cushion;
- moveArea.right -= Cushion;
- }
- else {
- DistMoved = 0;
- return;
- }
-
-
- if (!moveArea.Contains(*this)) {
- // Indicator out of move area to put it adjacent to either top or bottom
- // of move area.
- //
- if (left < moveArea.left) {
- left = moveArea.left;
- right = left + splitterWidth;
- }
- else {
- right = moveArea.right;
- left = right - splitterWidth;
- }
- }
- else
- DistMoved = dist;
- }
-
- //
- // Return distance moved (left or right) given starting and current point.
- //
- int
- TVSplitterIndicator::CalcDistMoved(const TPoint& start, const TPoint& cur)
- {
- return cur.x - start.x;
- }
-
- //
- // A check to see if given point could be in indicator if indicator were
- // streched. This function is used when determining if multiple splitters
- // intersect at a point (for dragging).
- //
- bool
- TVSplitterIndicator::CouldContain(const TPoint& point)
- {
- TRect r = *this;
- int splitterWidth = right - left;
-
- r.top -= splitterWidth;
- r.bottom += splitterWidth;
- return r.Contains(point);
- }
-
- //
- // Calculate the area in which the indicator moved. Use original splitter
- // position and current indicator position to calculate area. Used to
- // determine which panes need to be removed.
- //
- TRect
- TVSplitterIndicator::CalcAreaOfSplitterMove()
- {
- TRect r1 = *this;
- TRect r2 = Splitter->GetScreenRect();
- TRect area = r2;
-
- if (r1.left < r2.left) {
- area.left = r1.left;
- area.right = r2.right;
- }
- else {
- area.left = r2.left;
- area.right = r1.right;
- }
- return area;
- }
-
- //----------------------------------------------------------------------------
- // THSplitterIndicator class.
- //
-
- //
- // Connect either left or right side of indicator to either left or right side
- // of given TRect. If left side of given TRect is to the right of indicator
- // then connect to TRect's left side, else if TRect is to the left of indicator
- // then connect to TRect's right side. Assumes that given TRect represents a
- // vertical indicator.
- //
- void
- THSplitterIndicator::ConnectToRect(const TRect& rect)
- {
- if (rect.left > right)
- right = rect.left;
- else if (rect.left < left)
- left = rect.right;
- }
-
- //
- // Move splitter indicator (do not draw it though) given dist, which
- // could be + (move down) or - (move up). If the move would put the
- // indicator out of the move area then move to edge of move area.
- //
- void
- THSplitterIndicator::Move(int dist)
- {
- TRect moveArea = Splitter->GetMoveArea();
- TRect orig = Splitter->GetScreenRect();
- int splitterWidth = bottom - top;
-
- top = orig.top + dist;
- bottom = top + splitterWidth;
- left = orig.left;
- right = orig.right;
-
- //
- // Don't allow the indicator to get closer to the edge of the moveArea
- // than the cushion.
- //
- if( moveArea.Height() > (Cushion) ) {
- moveArea.top += Cushion;
- moveArea.bottom -= Cushion;
- }
- else {
- DistMoved = 0;
- return;
- }
-
- if (!moveArea.Contains(*this)) {
- // Indicator out of move area to put it adjacent to either top or bottom
- // of move area.
- //
- if (top < moveArea.top) {
- top = moveArea.top;
- bottom = top + splitterWidth;
- }
- else {
- bottom = moveArea.bottom;
- top = bottom - splitterWidth;
- }
- }
- else
- DistMoved = dist;
- }
-
- //
- // Return distance moved (up or down) given starting and current point.
- //
- int
- THSplitterIndicator::CalcDistMoved(const TPoint& start, const TPoint& cur)
- {
- return cur.y - start.y;
- }
-
- //
- // A check to see if given point could be in indicator if indicator were
- // streched. This function is used when determining if multiple splitters
- // intersect at a point (for dragging).
- //
- bool
- THSplitterIndicator::CouldContain(const TPoint& point)
- {
- TRect r = *this;
- int splitterWidth = bottom - top;
-
- r.left -= splitterWidth;
- r.right += splitterWidth;
-
- TPoint p = point;
- return r.Contains(point);
- }
-
- //
- // Calculate the area in which the indicator moved. Use original splitter
- // position and current indicator position to calculate area. Used to
- // determine which panes need to be removed.
- //
- TRect
- THSplitterIndicator::CalcAreaOfSplitterMove()
- {
- TRect r1 = *this;
- TRect r2 = Splitter->GetScreenRect();
- TRect area = r2;
-
- if (r1.top < r2.top) {
- area.top = r1.top;
- area.bottom = r2.bottom;
- }
- else {
- area.top = r2.top;
- area.bottom = r1.bottom;
- }
- return area;
- }
-
- //----------------------------------------------------------------------------
- // TSplitterIndicatorList class.
- //
-
- //
- // Search for indicator that was created from given splitter.
- //
- TSplitterIndicator*
- TSplitterIndicatorList::FindIndicatorWithSplitter(TSplitter* splitter)
- {
- TSplitterIndicatorListIterator iter(*this);
-
- while (iter != 0) {
- TSplitterIndicator* i = iter++;
- if (i->GetSplitter() == splitter)
- return i;
- }
- return 0;
- }
-
- //----------------------------------------------------------------------------
- // TSplitterIndicatorMgr class.
- //
-
- //
- // Save indicator list for later manipulation. Record starting drag point.
- // Draw splitter indicators.
- //
- void
- TSplitterIndicatorMgr::StartMove(TSplitterIndicatorList& sil,
- const TPoint& point)
- {
- SplitterIndicatorList = &sil;
- StartDragPoint = point;
- DrawIndicators();
- }
-
- //
- // Clear indicators from screen.
- //
- void
- TSplitterIndicatorMgr::EndMove()
- {
- ClearIndicators();
- }
-
- //
- // Move all indicators. Distance moved is based on starting drag point and
- // given point.
- //
- void
- TSplitterIndicatorMgr::MoveIndicators(const TPoint& point)
- {
- ClearIndicators();
-
- TSplitterIndicatorListIterator iter(*SplitterIndicatorList);
- if (iter) {
- TSplitterIndicator* main = iter.Current();
- TSplitterIndicator* si;
- while (iter) {
- si = iter++;
- int dist = si->CalcDistMoved(StartDragPoint, point);
- si->Move(dist);
- if (si != main)
- si->ConnectToRect(*main);
- }
- }
- DrawIndicators();
- }
-
- //
- // Draw indicators on screen.
- //
- void
- TSplitterIndicatorMgr::DrawIndicators()
- {
- if( !SplitterIndicatorList )
- return;
- TSplitterIndicatorListIterator iter(*SplitterIndicatorList);
- while (iter != 0)
- (iter++)->Draw();
- }
-
- //
- // Clear all indicators from screen.
- //
- void
- TSplitterIndicatorMgr::ClearIndicators()
- {
- if( !SplitterIndicatorList )
- return;
- TSplitterIndicatorListIterator iter(*SplitterIndicatorList);
- while (iter != 0)
- (iter++)->Clear();
- }
-
- //----------------------------------------------------------------------------
- // TPaneSplitter class
- //
-
- DEFINE_RESPONSE_TABLE1(TPaneSplitter, TLayoutWindow)
- EV_WM_SIZE,
- END_RESPONSE_TABLE;
-
-
- //
- // Initialize data members.
- //
- TPaneSplitter::TPaneSplitter(TWindow* parent,
- const char far* title,
- int splitterWidth,
- TModule* module)
- :
- TLayoutWindow(parent, title, module),
- ShouldDelete(TShouldDelete::NoDelete),
- SplitterWidth(splitterWidth),
- SplitterCushion(0),
- Dragging(false),
- PaneSplitterResizing(false)
- {
- if (!SplitterWidth)
- SplitterWidth = TSystem::Has3dUI() ? TUIMetric::CxFixedFrame
- : TUIMetric::CxSizeFrame;
- SetCaption("PaneSplitter");
- }
-
- //
- // Empty destructor
- //
- TPaneSplitter::~TPaneSplitter()
- {
- }
-
- //
- // Load cursors and set TSplitter's pane splitter object.
- //
- void
- TPaneSplitter::SetupWindow()
- {
- TLayoutWindow::SetupWindow();
-
- // Load cursors.
- //
- #if defined(USE_CUSTOM_CURSORS)
- ResizeCursorH = GetModule()->LoadCursor(IDC_RESIZE_H);
- ResizeCursorV = GetModule()->LoadCursor(IDC_RESIZE_V);
- ResizeCursorHV = GetModule()->LoadCursor(IDC_RESIZE_HV);
- #else
- ResizeCursorH = ::LoadCursor(0, IDC_SIZENS);
- ResizeCursorV = ::LoadCursor(0, IDC_SIZEWE);
- ResizeCursorHV = ::LoadCursor(0, IDC_SIZEALL);
- #endif
- }
-
- //
- // Remove all panes (and related splitters). Destroy cursors.
- //
- void
- TPaneSplitter::CleanupWindow()
- {
- RemoveAllPanes();
-
- #if defined(USE_CUSTOM_CURSORS)
- ::DestroyCursor(ResizeCursorH);
- ::DestroyCursor(ResizeCursorV);
- ::DestroyCursor(ResizeCursorHV);
- #endif
-
- TLayoutWindow::CleanupWindow();
- }
-
- //
- // Set data member 'PaneSplitterResizing' to indicate that contained
- // splitters should adjust themselves according to their percentage.
- //
- void
- TPaneSplitter::EvSize(uint sizeType, TSize& size)
- {
- PaneSplitterResizing = true;
- TLayoutWindow::EvSize(sizeType, size);
- PaneSplitterResizing = false;
- }
-
- //
- // Called by TSplitter when it needs to draw itself.
- // Default behavior provided in this base class is to draw a 3dface splitter.
- //
- void
- TPaneSplitter::DrawSplitter(TDC& dc, const TRect& splitter)
- {
- dc.TextRect(splitter, TColor::Sys3dFace);
- if (!TSystem::Has3dUI())
- TUIBorder(splitter, TUIBorder::WndRaised).Paint(dc);
- }
-
- //
- // Split given pane, 'target', with 'newPane' in either the vertical or
- // horizontal direction. Creates a new splitter.
- //
- bool
- TPaneSplitter::SplitPane(TWindow* target, TWindow* newPane,
- TSplitDirection splitDir, float percent)
- {
- PRECONDITION(target);
- PRECONDITION(target != newPane);
-
- if (GetFirstChild() == 0) { // if no panes.
- TLayoutMetrics lmOfTarget;
-
- GetDefLM(lmOfTarget);
- target->SetParent(this);
- target->Create();
- SetChildLayoutMetrics(*target, lmOfTarget);
- Layout();
- }
-
- if (newPane) {
- if (!HasPane(target))
- return false;
-
- TSplitter* splitter;
- TLayoutWindow* parentSplitter = LAYOUTWINDOW(target->Parent);
-
- if (parentSplitter == this) { // if first split.
- if (splitDir == psHorizontal)
- splitter = new THSplitter(target->Parent, this, percent);
- else
- splitter = new TVSplitter(target->Parent, this, percent);
- splitter->Create();
- splitter->SetPercent(percent);
-
- TLayoutMetrics lm = splitter->Setup(target, newPane, percent);
- parentSplitter->SetChildLayoutMetrics(*splitter, lm);
- }
- else {
- // Ask splitter to split itself.
- //
- SPLITTER(parentSplitter)->Split(target, newPane, splitDir, percent);
- }
- parentSplitter->Layout();
- }
- return true;
- }
-
- //
- // Remove given pane from TPaneSplitter, deleting it if requested.
- // This operation has the side effect of removing the splitter it was
- // contained in.
- //
- bool
- TPaneSplitter::RemovePane(TWindow* pane, TPaneSplitter::TDelete dt)
- {
- TLayoutWindow* layoutWin = DoRemovePane(pane, dt);
- if (layoutWin) {
- PaneSplitterResizing = true;
- layoutWin->Layout();
- PaneSplitterResizing = false;
- return true;
- }
- return false;
- }
-
- //
- // Replace 'target' pane (must exist) with 'newPane' (does not exist).
- // 'target' may be deleted, depends on 'dt'.
- //
- bool
- TPaneSplitter::ReplacePane(TWindow* target, TWindow* newPane,
- TPaneSplitter::TDelete dt)
- {
- if (!HasPane(target) || HasPane(newPane)) // 'newPane' should not exist.
- return false;
-
- if (target->CanClose()) { // 'newPane' takes on target's layout metrics.
- TLayoutMetrics lmOfTarget;
- TLayoutMetrics lmOfOther;
- TLayoutWindow* splitter = LAYOUTWINDOW(target->Parent);
- TWindow* pane1 = splitter->GetFirstChild();
- TWindow* pane2 = 0;
-
- if (SPLITTER(splitter)) {
- pane1 = SPLITTER(splitter)->Pane1();
- pane2 = SPLITTER(splitter)->Pane2();
- }
- splitter->GetChildLayoutMetrics(*target, lmOfTarget);
-
- if (pane1 == target && pane2) {
- splitter->GetChildLayoutMetrics(*pane2, lmOfOther);
- if (lmOfOther.X.RelWin == target)
- lmOfOther.X.RelWin = newPane;
- else
- lmOfOther.Y.RelWin = newPane;
- splitter->SetChildLayoutMetrics(*pane2, lmOfOther);
- }
- newPane->SetParent(splitter);
- newPane->Create();
- splitter->SetChildLayoutMetrics(*newPane, lmOfTarget);
- splitter->RemoveChildLayoutMetrics(*target);
- DestroyPane(target, dt);
- splitter->Layout();
- return true;
- }
- return false;
- }
-
- //
- // Swap given panes (must exist). Panes take on each others layout metrics.
- //
- bool
- TPaneSplitter::SwapPanes(TWindow* pane1, TWindow* pane2)
- {
- if (!HasPane(pane1) || !HasPane(pane2))
- return false;
-
- TSplitter* splitter1 = SPLITTER(pane1->Parent);
- TSplitter* splitter2 = SPLITTER(pane2->Parent);
-
- if (splitter1 != splitter2) {
- TLayoutMetrics lmOfPane1;
- TLayoutMetrics lmOfPane2;
- TLayoutMetrics lmOfOther;
- TWindow* paneA = splitter1->Pane1();
- TWindow* paneB = splitter1->Pane2();
-
- splitter1->GetChildLayoutMetrics(*pane1, lmOfPane1);
- splitter2->GetChildLayoutMetrics(*pane2, lmOfPane2);
-
- if (paneA == pane1) { // if top or left pane.
- splitter1->GetChildLayoutMetrics(*paneB, lmOfOther);
- pane1->SetParent(0);
- if (lmOfOther.X.RelWin == pane1)
- lmOfOther.X.RelWin = pane2;
- else
- lmOfOther.Y.RelWin = pane2;
- splitter1->SetChildLayoutMetrics(*paneB, lmOfOther);
- }
-
- paneA = splitter2->Pane1();
- paneB = splitter2->Pane2();
- if (paneA == pane2) { // if top or left pane.
- splitter2->GetChildLayoutMetrics(*paneB, lmOfOther);
- pane2->SetParent(0);
- if (lmOfOther.X.RelWin == pane2)
- lmOfOther.X.RelWin = pane1;
- else
- lmOfOther.Y.RelWin = pane1;
- splitter2->SetChildLayoutMetrics(*paneB, lmOfOther);
- }
- pane1->SetParent(splitter2);
- pane2->SetParent(splitter1);
- splitter1->SetChildLayoutMetrics(*pane2, lmOfPane1);
- splitter2->SetChildLayoutMetrics(*pane1, lmOfPane2);
- splitter1->Layout();
- splitter2->Layout();
- }
- else {
- TLayoutWindow* lw = LAYOUTWINDOW(pane1->Parent);
- TLayoutMetrics lmOfPane1;
- TLayoutMetrics lmOfPane2;
-
- lw->GetChildLayoutMetrics(*pane1, lmOfPane1);
- lw->GetChildLayoutMetrics(*pane2, lmOfPane2);
-
- if (lmOfPane1.X.RelWin == pane2)
- lmOfPane1.X.RelWin = pane1;
- else if (lmOfPane2.X.RelWin == pane1)
- lmOfPane2.X.RelWin = pane2;
- else if (lmOfPane1.Y.RelWin == pane2)
- lmOfPane1.Y.RelWin = pane1;
- else
- lmOfPane2.Y.RelWin = pane2;
-
- lw->SetChildLayoutMetrics(*pane1, lmOfPane2);
- lw->SetChildLayoutMetrics(*pane2, lmOfPane1);
- lw->Layout();
- }
- return true;
- }
-
- //
- // Iterate over each pane. if 'callback' returns 0 then iteration stops.
- //
- void
- TPaneSplitter::ForEachPane(TPaneSplitter::TForEachPaneCallback callback,
- void* p)
- {
- ForEachObject(GetFirstChild(), &TPaneSplitter::DoForEachPane,
- (void*)callback, p);
- }
-
- //
- // Return number of panes in TPaneSplitter.
- //
- int
- TPaneSplitter::PaneCount()
- {
- int nPanes = 0;
-
- ForEachObject(GetFirstChild(), &TPaneSplitter::DoPaneCount, &nPanes, 0);
- return nPanes;
- }
-
- //
- // Remove all the panes (and their splitters). If any pane can't close
- // then abort the operation.
- //
- void
- TPaneSplitter::RemoveAllPanes(TDelete dt)
- {
- TListImp<TWindow*> wList;
-
- // Remove and delete (depending on 'dt') all panes.
- //
- ForEachObject(GetFirstChild(), &TPaneSplitter::GetPanes, &wList, 0);
- TListIteratorImp<TWindow*> wListIter(wList);
-
- // check to see if a pane can't close, if so abort operation.
- //
- while (wListIter != 0)
- if (!(wListIter++)->CanClose())
- return;
- wListIter.Restart();
- while (wListIter != 0) // remove all the panes.
- RemovePane(wListIter++, dt);
- }
-
- //
- // Set the splitter width and adjust all splitters, takes effect immediately.
- //
- int
- TPaneSplitter::SetSplitterWidth(int newWidth)
- {
- int oldWidth = SplitterWidth;
- int widthDiff = newWidth - SplitterWidth;
-
- SplitterWidth = newWidth;
- ForEachObject(GetFirstChild(), &TPaneSplitter::AdjSplitterWidth, &widthDiff,
- 0);
- return oldWidth;
- }
-
- //
- // Move 'pane' given distance. if 'pane' does not exist or there are
- // no splitters or removal of a pane failed then false is returned, else true.
- //
- bool
- TPaneSplitter::MoveSplitter(TWindow* pane, int dist)
- {
- if (!HasPane(pane) || pane->Parent == this )
- return false;
-
- TSplitter* splitter = SPLITTER(pane->Parent);
- TSplitterIndicator* si = splitter->CreateSplitterIndicator();
- si->SetCushion( SplitterCushion );
-
- SplitterIndicatorList.Flush(1);
- SplitterIndicatorList.Add(si);
- si->Move(dist);
- if (RemovePanes() == 0) {
- MoveSplitters();
- SplitterIndicatorList.Flush(1);
- return true;
- }
- return false;
- }
-
- //
- // Private Member Functions...
- //
-
- //
- // Notify indicator mgr to move the indicators.
- //
- void
- TPaneSplitter::MouseMoved(const TPoint& point)
- {
- if (Dragging)
- SplitterIndicatorMgr.MoveIndicators(point);
- }
-
- //
- // Set capture (for mouse dragging) and notify indicator mgr that
- // we are starting to move the indicators.
- //
- void
- TPaneSplitter::StartSplitterMove(TSplitter* splitter, const TPoint& point)
- {
- Dragging = true;
- splitter->SetCapture();
- SplitterIndicatorMgr.StartMove(SplitterIndicatorList, point);
- }
-
- //
- // Release the capture and notify indicator mgr that we have stopped moving
- // the indicators. Remove any panes that were 'covered' by the move.
- // Finally, move the splitters.
- //
- void
- TPaneSplitter::EndSplitterMove()
- {
- if( !Dragging )
- return;
- Dragging = false;
- ReleaseCapture();
- SplitterIndicatorMgr.EndMove();
- if (RemovePanes() == 0) {
- MoveSplitters();
- SplitterIndicatorList.Flush(1);
- }
- }
-
- //
- // Set the appropriate cursor depending on the number of splitters
- // that will be moved.
- //
- void
- TPaneSplitter::SetSplitterMoveCursor(TSplitter* splitter, const TPoint& point)
- {
- if (!Dragging)
- FindIntersectingSplitters(point);
-
- if (SplitterIndicatorList.NSplitterIndicators() > 1)
- ::SetCursor(ResizeCursorHV);
- else if (splitter->SplitDirection() == psHorizontal)
- ::SetCursor(ResizeCursorH);
- else
- ::SetCursor(ResizeCursorV);
- }
-
- //
- // Private structure for splitter and pane traversal.
- //
- struct TTraversalRec {
- TTraversalRec() : Cnt(0), Object(0) {}
- TTraversalRec(TWindow* o) : Cnt(0), Object(o) {}
- TTraversalRec(const TTraversalRec& r) : Cnt(r.Cnt), Object(r.Object) {}
-
- int operator == (const TTraversalRec& r) const { return Object == r.Object; }
- TTraversalRec& operator = (const TTraversalRec& r);
-
- char Cnt;
- TWindow* Object;
- };
-
- TTraversalRec&
- TTraversalRec::operator = (const TTraversalRec& r)
- {
- Cnt = r.Cnt; Object = r.Object;
- return *this;
- }
-
- //
- // Iterate over the splitters and panes, calling 'callback' on each.
- // allows for 2 parameters to be passed. Traverses the objects in
- // one of three order: InOrder, PreOrder and PostOrder.
- //
- void
- TPaneSplitter::ForEachObject(TWindow* o, TForEachObjectCallback callback,
- void* p1, void* p2, TTraversalOrder order)
- {
- if (!o)
- return;
-
- TStackAsList<TTraversalRec> stack;
- TTraversalRec trec;
- int done = 0;
-
- stack.Push(TTraversalRec(o));
- while (!done) {
- trec = stack.Pop();
- trec.Cnt++;
- if ((order == psPreOrder && trec.Cnt == 1) ||
- (order == psInOrder && trec.Cnt == 2) ||
- (order == psPostOrder && trec.Cnt == 3))
- done = !(this->*callback)(trec.Object, p1, p2);
-
- if (!done) {
- if (trec.Cnt != 3) {
- stack.Push(trec);
- if (trec.Cnt == 1 && SPLITTER(trec.Object))
- stack.Push(TTraversalRec(SPLITTER(trec.Object)->Pane1()));
- else if (trec.Cnt == 2 && SPLITTER(trec.Object) &&
- SPLITTER(trec.Object)->Pane2())
- stack.Push(TTraversalRec(SPLITTER(trec.Object)->Pane2()));
- }
- done = stack.IsEmpty();
- }
- }
- }
-
- //
- // Set default TLayoutMetrics. Everything relative to parent.
- //
- void
- TPaneSplitter::GetDefLM(TLayoutMetrics& lm)
- {
- lm.SetMeasurementUnits(lmPixels);
- lm.X.SameAs(lmParent, lmLeft);
- lm.Y.SameAs(lmParent, lmTop);
- lm.Width.Set(lmRight, lmSameAs, lmParent, lmRight);
- lm.Height.Set(lmBottom, lmSameAs, lmParent, lmBottom);
- }
-
- //
- // Return true if this TPaneSplitter contains 'p' (pane or splitter).
- //
- bool
- TPaneSplitter::HasPane(TWindow* p)
- {
- TWindow* parent = p->Parent;
- while (parent) {
- if (parent == this)
- return true;
- parent = parent->Parent;
- }
- return false;
- }
-
- //
- // Do the work of removing given pane.
- //
- TLayoutWindow*
- TPaneSplitter::DoRemovePane(TWindow* pane, TPaneSplitter::TDelete dt)
- {
- if (!HasPane(pane) || !pane->CanClose())
- return 0;
-
- TSplitter* splitter = SPLITTER(pane->Parent);
- TLayoutWindow* retval = this;
-
- if (splitter) {
- retval = splitter->RemovePane(pane, dt);
- splitter->Destroy();
- delete splitter;
- }
- else {
- RemoveChildLayoutMetrics(*pane);
- DestroyPane(pane, dt);
- }
- return retval;
- }
-
- //
- // Find intersecting splitters. Called when splitters will be moved.
- //
- void
- TPaneSplitter::FindIntersectingSplitters(const TPoint& point)
- {
- TPoint p = point;
-
- SplitterIndicatorList.Flush(1);
- ForEachObject(GetFirstChild(), &TPaneSplitter::DoFindIntersectingSplitters,
- &SplitterIndicatorList, &p);
- }
-
- //
- // Remove any panes 'covered' as a result of a splitter move.
- //
- int
- TPaneSplitter::RemovePanes()
- {
- TListImp<TSplitterIndicator*> tempList; // don't process indicators.
- TSplitterIndicatorListIterator iter(SplitterIndicatorList);
- TSplitterIndicator* si;
- int nPanesNotRemoved = 0;
-
- while (iter != 0) {
- si = iter++;
-
- if (!tempList.Find(si)) { // if indicator not in list then process it.
- TRect area = si->CalcAreaOfSplitterMove();
- TListImp<TWindow*> list; // list of panes to remove.
- ForEachObject(GetFirstChild(), &TPaneSplitter::GetListOfPanesToRemove,
- &list, &area);
- TListIteratorImp<TWindow*> listIter(list);
- while (listIter != 0) {
- TWindow* pane = listIter++;
- TSplitterIndicator* i;
- if ((i = SplitterIndicatorList.FindIndicatorWithSplitter(
- SPLITTER(pane->Parent))) != 0)
- tempList.Add(i);
- if (!RemovePane(pane)) {
- tempList.Add(i);
- nPanesNotRemoved++;
- break;
- }
- }
- }
- }
- TListIteratorImp<TSplitterIndicator*> tempIter(tempList);
- while (tempIter != 0) // remove panes not to be moved from list.
- SplitterIndicatorList.Detach(tempIter++, 1);
- return nPanesNotRemoved;
- }
-
- //
- // Move all splitters.
- //
- void
- TPaneSplitter::MoveSplitters()
- {
- TSplitterIndicatorListIterator iter(SplitterIndicatorList);
- while (iter != 0) {
- TSplitterIndicator* si = iter++;
- si->GetSplitter()->Move(si->GetDistMoved());
- si->GetSplitter()->Layout();
- }
- }
-
- //
- // Destroy a pane, deleting the OWL object if requested
- //
- void
- TPaneSplitter::DestroyPane(TWindow* pane, TDelete dt)
- {
- pane->ShowWindow(SW_HIDE); // so user can't see.
- pane->SetParent(0);
- pane->Destroy();
- if (DelObj(dt))
- delete pane;
- }
-
- //
- // ForEachObject callbacks...
- //
-
- //
- // Iterate over all panes.
- //
- int
- TPaneSplitter::DoForEachPane(TWindow* o, void *p1, void*p2)
- {
- if (!SPLITTER(o))
- return ((TForEachPaneCallback)p1)(*o, p2);
- return 1;
- }
-
- //
- // Find intersecting splitters. Determine which splitters to move.
- //
- int
- TPaneSplitter::DoFindIntersectingSplitters(TWindow* o, void *p1, void*p2)
- {
- TSplitter* splitter = SPLITTER(o);
- if (splitter) {
- TSplitterIndicator* i = splitter->CreateSplitterIndicator();
- i->SetCushion( SplitterCushion );
- if (i->CouldContain(*(TPoint*)p2))
- ((TSplitterIndicatorList*)p1)->Add(i);
- else
- delete i;
- }
- return 1;
- }
-
- //
- // Get a list of panes that will be removed as a result of a splitter move.
- //
- int
- TPaneSplitter::GetListOfPanesToRemove(TWindow* o, void *p1, void*p2)
- {
- if (!SPLITTER(o)) {
- TRect r = o->GetWindowRect();
- if ((*(TRect*)p2).Contains(r))
- ((TListImp<TWindow*>*)p1)->Add(o);
- }
- return 1;
- }
-
- //
- // Change the width of every splitter.
- //
- int
- TPaneSplitter::AdjSplitterWidth(TWindow* o, void *p1, void*)
- {
- TSplitter* splitter = SPLITTER(o);
-
- if (splitter)
- splitter->AdjSplitterWidth(*(int *)p1);
- return 1;
- }
-
- //
- // Calculate number of panes.
- //
- int
- TPaneSplitter::DoPaneCount(TWindow* o, void *p1, void*)
- {
- if (!SPLITTER(o))
- (*(int*)p1)++;
- return 1;
- }
-
- //
- // Get a list of all the panes.
- //
- int
- TPaneSplitter::GetPanes(TWindow* o, void *p1, void*)
- {
- if (!SPLITTER(o))
- ((TListImp<TWindow*> *)p1)->Add(o);
- return 1;
- }
-
- //
- // Get a list of all splitters.
- //
- int
- TPaneSplitter::GetSplitters(TWindow* o, void* p1, void*)
- {
- if (SPLITTER(o))
- ((TListImp<TWindow*>*)p1)->Add(o);
- return 1;
- }
-